﻿/*
 * 使用前先安装插件
 * npm install -g minimist 接收命令行参数插件
 * npm install -g imagemin
 *  npm install -g imagemin-mozjpeg
 *   npm install -g imagemin-pngquant
 *    npm install -g imagemin-giflossy
 *     npm install -g imagemin-webp
 *      npm install -g imagemin-svgo
*/
// Colors for console.log messages
const COLORS = {
    yellow: '\x1b[33m%s\x1b[0m'
};

console.log("***********************************************************************")
console.log("\t node+imagemin 压缩图片命令行工具,支持png,jpg,svg,gif")
console.log("\r\n");
console.log("example :  node png_jpg_webp_gif_svg_compress.js [options]");
console.log("\r\n");
console.log("options : \r\n");
console.log("\t --indir \t 要压缩的目录路径");
console.log("\t --outdir \t 压缩后文件输出目录路径");
console.log("***********************************************************************")
console.log("\r\n\r\n");
const basePath ='C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\MSBuild\\Microsoft\\VisualStudio\\NodeJs\\node_modules\\'
const args = require(basePath+'minimist')(process.argv.slice(2));
const imagemin = require(basePath +'imagemin');

// Lossy Plugins
//const imageminMozjpeg = require('imagemin-mozjpeg');
const imageminPngquant = require(basePath +'imagemin-pngquant');
//const imageminGiflossy = require('imagemin-giflossy');
//const imageminWebp = require('imagemin-webp');
const imageminSvgo = require(basePath +'imagemin-svgo');

// Lossyless Plugin
const imageminJpegtran = require(basePath+'imagemin-jpegtran');
//const imageminOptipng = require('imagemin-optipng');
const imageminGifsicle = require(basePath+'imagemin-gifsicle');

const { lstatSync, readdirSync } = require('fs');
const { join, normalize,isAbsolute } = require('path');

//default Source directory for images to be optimized
var INPUT_DIR = 'images';

//default Destiny for compressed images
var OUTPUT_DIR = 'build';

if (args.indir)
    INPUT_DIR = args.indir;
if (!isAbsolute(INPUT_DIR))
    INPUT_DIR = join(process.cwd(), INPUT_DIR);
if (args.outdir)
    OUTPUT_DIR = args.outdir;
if (!isAbsolute(OUTPUT_DIR))
    OUTPUT_DIR = join(process.cwd(), OUTPUT_DIR);


/**
 * Return true if source is a directory.
 * @param {string} source Directory.
 */
const isDirectory = source => lstatSync(source).isDirectory();

/**
 * Get directories for a given directory.
 * @param {string} source Directory.
 */
const getDirectories = source =>
    readdirSync(source)
        .map(name => join(source, name))
        .filter(isDirectory);

/**
 * Recursive function that get list of all directories and subdirectories for
 * a given directory.
 * @param {string} source Root directory.
 */
const getDirectoriesRecursive = source => [
    normalize(source),
    ...getDirectories(source)
        .map(getDirectoriesRecursive)
        .reduce((a, b) => a.concat(b), [])
];

/**
 * Convert Windows backslash paths to slash paths.
 * @param {string} path
 */
const converToSlash = path => {
    const isExtendedLengthPath = /^\\\\\?\\/.test(path);
    //const hasNonAscii = /[^\u0000-\u0080]+/.test(path);
    
    if (isExtendedLengthPath ) {
        return path;
    }

    return path.replace(/\\/g, '/');
};

console.log(COLORS.yellow, 'Beginning image compression.');
console.log("当前输入路径：" + INPUT_DIR);
console.log("当前输出路径：" + OUTPUT_DIR);
(async () => {
    const imageDirs = getDirectoriesRecursive(INPUT_DIR);
    let imagesOptimized = 0;

    /**
     * Loop through all subfolders, and recursively run imagemin,
     * outputting to the same subfolders inside OUTPUT_DIR folder.
     */
    for (let i in imageDirs) {
        const dir = imageDirs[i];

        /**
         * imagemin needs paths with forward slashes. converToSlash is needed
         * on Windows environment.
         *
         * Remove INPUT_DIR in OUTPUT_DIR for just getting the part of folder wanted.
         * If not replaced, the output would be: static/img/static-src/img/**
         */
        
        
        const destiny = converToSlash(join(OUTPUT_DIR, dir.replace(INPUT_DIR, '')));
   
        const files = await imagemin([`${converToSlash(dir)}/*.{jpg,png,svg,gif}`], {
            destination: normalize(destiny),
            plugins: [
                imageminJpegtran(),
                imageminPngquant({
                    quality: [0.6, 0.8]
                }),
                imageminGifsicle(),
                imageminSvgo({
                    plugins: [{ removeViewBox: false }]
                })
            ]
        });
        imagesOptimized += files.length;
    }

    console.log(COLORS.yellow, `Image compression finished. Total images compressed: ${imagesOptimized}`);
})();